package breadbox.pastry;

public class LongID implements ID {
	private static final long serialVersionUID = 6546020269884744247L;
	private int base_;
	private long id_;
	
	public LongID( long id ) {
		base_ = (int) Math.ceil( Math.pow( 2.0, Conf.b( ) ) );
		id_ = id;
	}
	
	public int base() {
		return base_;
	}

	public String commonPrefix(ID other) {
		StringBuffer prefix = new StringBuffer();
		
		String one = toString( base_ );
		String two = other.toString( base_ );
		
		int len = Math.min( one.length(), two.length() );
		
		for( int i = 0; i < len; i++ ) {
			if( one.charAt( i ) == two.charAt( i ) ) {
				prefix.append( one.charAt( i ) );
			} else {
				break;
			}
		}
		
		return prefix.toString();
	}

	public String toString(int base) {
		String s = Long.toString( id_, base );

		// TODO HACK for length
		int len = 16;
		
		if( s.length() < len ) {
			StringBuilder sb = new StringBuilder();
			for( int i = s.length(); i < len; i++ ) {
				sb.append( "0" );
			}
			
			sb.append(s);
			s = sb.toString();
		}
		
		return s;
	}

	/**
	 * Assumes string representations of each ID will have the same length
	 */
	public int compareTo(ID o) {
//		String prefix = commonPrefix(o);
//		int end = prefix.length();
//		String id1 = toString(base_);
//		String id2 = o.toString(base_);
//		long diff = 0;
//		
//		for( int i = id1.length() - 1, base = 1; i > end; i--, base *= base_ ) {
//			try {
//				Integer int1 = Integer.parseInt( id1.substring(i, i + 1) );
//				Integer int2 = Integer.parseInt( id2.substring(i, i + 1) );
//				
//				diff += int1 - int2;
//				
//			} catch( NumberFormatException e ) {
//				
//			}
//		}
//		
//		return (int)diff;
		return toString(base_).compareTo(o.toString(base_));
	}
	
	public long distance(ID o) {
		Long other = null;
		
		try {
			other = Long.parseLong(o.toString(base_), base_);
		} catch (NumberFormatException e) {
			return (long) compareTo(o);
		}
		
		return Math.abs(id_ - other);
	}
	
	public boolean equals(ID o) {
		return compareTo(o) == 0;
	}
	
	@Override
	public String toString( ) {
		return toString( base() );
	}

}
